package org.jsoncrypto;

import static org.junit.Assert.*;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.json.JSONException;
import org.json.JSONObject;
import org.jsoncrypto.util.Base64;
import org.junit.Test;

public class JweA256KWtest {

    @Test
    public void test() throws JcBaseException, JSONException {
      final String joeStr = "{\"iss\":\"joe\",\r\n" + " \"exp\":1300819380,\r\n"
          + " \"http://example.com/is_root\":true}";

      final String a256kw = "{\"alg\":\"A256KW\", \"enc\":\"A256GCM\", \"iv\":\"AxY8DCtDaGlsbGljb3RoZQ\"}";
      JSONObject header = new JSONObject(a256kw);
      JcLibEnc_AEAD enc = new JcEnc_A256GCM(header);
      JweA256KW jwe = new JweA256KW(enc);
      byte[] contentBytes = joeStr.getBytes();
      SecretKey key = new SecretKeySpec("password12345678".getBytes(), "AES");

      String encrypted = jwe.encrypt(contentBytes, key);
      String[] split = encrypted.split("\\.");
      assertEquals(4, split.length);
      
      JweA256KW x = new JweA256KW(encrypted);
      byte[] bytes = x.decrypt(key);
      assertEquals(joeStr, new String(bytes));
    }

    @Test
    public void testManipulatedHeader() {
      String encrypted = null;
      try {
        final String joeStr = "{\"iss\":\"joe\",\r\n" + " \"exp\":1300819380,\r\n"
            + " \"http://example.com/is_root\":true}";
    
        final String a256kw = "{\"alg\":\"A256KW\", \"enc\":\"A256GCM\", \"iv\":\"AxY8DCtDaGlsbGljb3RoZQ\"}";
        JSONObject header = new JSONObject(a256kw);
        JcLibEnc_AEAD enc = new JcEnc_A256GCM(header);
        JweA256KW jwe = new JweA256KW(enc);
        byte[] contentBytes = joeStr.getBytes();
        SecretKey key = new SecretKeySpec("password12345678".getBytes(), "AES");
    
        encrypted = jwe.encrypt(contentBytes, key);
        String[] split = encrypted.split("\\.");
        assertEquals(4, split.length);
        String jweHeaderStr = new String(Base64.decodeUrl(split[0]));
        JSONObject jweHeader = new JSONObject(jweHeaderStr);
        jweHeader.put("new", "bogus");
        jweHeaderStr = Base64.encodeBytes(
            jweHeader.toString().getBytes("utf-8"),
            org.jsoncrypto.util.Base64.DONT_BREAK_LINES
                | org.jsoncrypto.util.Base64.URL);
        encrypted = jweHeaderStr + "." + split[1] + "." + split[2] + "." + split[3];
        JweA256KW jweA256KW = new JweA256KW(encrypted);
        jweA256KW.decrypt(key);
        fail("should not be reached because the integrity check fails");
      } catch (Exception e) {
        Throwable t = e.getCause();
        if (!(t instanceof org.bouncycastle.crypto.InvalidCipherTextException)) {
          fail();
        }
      }
    }

  }
